
#if CONFIG_IPMB_TESTER
#include "IpmbTester.h"
#include "Debug.h"
#include "os.h"
#include "Cmdhandler.h"
#include "Command_Define.h"
#include "EventData.h"
#include "Sensor.h"
#include "Mmc.h"
#include "i2c_module_interface.h"
#include "CheckSum.h"

int IpmbTester_PostMsg(IpmbTester* pIpmbTester, uint8 object, uint8 msgID, uint32 param1, uint32 param2)
{
	int iResult = ERR_SUCCESS;

	if(QUEUE_isFull(&pIpmbTester->m_msgQueue))
	{
		Trace("%s() g_Emmc.m_msgQueue is Full!\n", _FUNC_);
	}
	else
	{
		Message msg;
		msg.m_ObjectID = object;
		msg.m_MsgID = msgID;
		msg.m_Param1 = param1;
		msg.m_Param2 = param2;
		QUEUE_add(&pIpmbTester->m_msgQueue, &msg);
	}
	
	return iResult;
}

void IpmbTester_CrbClone(Crb* pDstCrb, Crb* pSrcCrb)
{
	memcpy(pDstCrb->m_pReqIpmiCmd, pSrcCrb->m_pReqIpmiCmd, sizeof(IpmiCmd));
	memcpy(pDstCrb->m_pReqIpmiCmd->m_pCmd, pSrcCrb->m_pReqIpmiCmd->m_pCmd, pSrcCrb->m_pReqIpmiCmd->m_CmdLen);

	memcpy(pDstCrb->m_pRspIpmiCmd, pSrcCrb->m_pRspIpmiCmd, sizeof(IpmiCmd));
	memcpy(pDstCrb->m_pRspIpmiCmd->m_pCmd, pSrcCrb->m_pRspIpmiCmd->m_pCmd, pSrcCrb->m_pRspIpmiCmd->m_CmdLen);
	
	pDstCrb->m_State 		= pSrcCrb->m_State;
	pDstCrb->m_ErrorCode 	= pSrcCrb->m_ErrorCode;
	pDstCrb->m_MaxSendCount = pSrcCrb->m_MaxSendCount;
	pDstCrb->m_bTxCount 	= pSrcCrb->m_bTxCount;
	pDstCrb->m_IsForSendReq = pSrcCrb->m_IsForSendReq;

}

void IpmbTester_CrbTxRspDone(IpmbTester* pIpmbTester, Crb* pCrb, uint8 State)
{
	IpmbTester_CrbClone((Crb*)&pIpmbTester->m_FroRspCrb, pCrb);
	QUEUE_removeAll(pIpmbTester->m_IicDriver.m_pTxQueue);
}

void IpmbTester_Run(IpmbTester* pIpmbTester, IpmbRunFun IpmbRun)
{
    Message* pMsg = Null;
	
    while(1)
    {	
        pMsg = (Message*)QUEUE_getHead(&pIpmbTester->m_msgQueue);
        if(pMsg) 
        {
			//TRACE_LEVEL(TRACE_MAIN, ("%s(msgId=%d)\n", _FUNC_, pMsg->m_MsgID));
            if(OBJECT_IPMB & pMsg->m_ObjectID)
            {
                Assert(pMsg->m_Param1);
                Ipmb_msgProc((Ipmb*)pMsg->m_Param1, pMsg->m_MsgID, pMsg->m_Param2);
            }
        	QUEUE_removeHead(&pIpmbTester->m_msgQueue);
        }

		if(IpmbRun)
		{
			IpmbRun();
		}

		sleep(1);
    }   
}

int IpmbTester_ReqPlatformEvent(uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen) 
{
	EventReqMsg* pEventReqMsg = (EventReqMsg*)&pReqCmd;
	Sensor* pSensor = Mmc_GetSensor(pEventReqMsg->m_SensorId);

	Assert(pSensor);

	Trace("Sensor:%s[%d] PlatformEvent:\t", pSensor->m_IdString, pEventReqMsg->m_SensorId);
	EventData_Dump(&pEventReqMsg->m_EventData);

	pRspCmd[0] = COMMAND_COMPLETE;

	* pRspLen = 1;

	return ERR_SUCCESS;
}
/*
const IpmiCmdHandler g_CmTestCmdHandlers[] = 
{
	{NETFUN_SSEVENT_REQ ,PLATFORM_EVENT_MESSAGE	,(CmdHandlerFun)IpmbTester_ReqPlatformEvent}
};
*/
void IpmbTester_Reset(IpmbTester* pIpmbTester)
{
	Crb* pCrb = ((Crb*)&pIpmbTester->m_FroReqCrb);
	
	Ipmb_CancelCrb(&pIpmbTester->m_Ipmb, (Crb*)&pIpmbTester->m_ReqCrb);
	Ipmb_CancelCrb(&pIpmbTester->m_Ipmb, (Crb*)&pIpmbTester->m_RspCrb);
	Crb_Reset((Crb*)&pIpmbTester->m_ReqCrb);
	Crb_Reset((Crb*)&pIpmbTester->m_RspCrb);
	
	QUEUE_removeAll(pIpmbTester->m_IicDriver.m_pTxQueue);
	QUEUE_removeAll(pIpmbTester->m_IicDriver.m_pRxQueue);
	QUEUE_removeAll(&pIpmbTester->m_IicDriver.m_EventQueue);
	QUEUE_removeAll(&pIpmbTester->m_reqDataQueue);

	pCrb = ((Crb*)&pIpmbTester->m_FroReqCrb);
	pCrb = ((Crb*)&pIpmbTester->m_FroRspCrb);
	Crb_Reset(pCrb);
	
	pCrb = (Crb*)&pIpmbTester->m_RspCrb;	
	pCrb->m_pRequester = pIpmbTester;
	pCrb->Notify = (CrbNotifyFun)IpmbTester_CrbTxRspDone;
}

uint8 IpmbTester_CmdDisptch(const IicMsg* pReq
	, uint8 reqlen
	, const IpmiCmdHandler* pTable
	, uint8 count
	, uint8* pRspBuff
	, uint8 rspBufLen
	)
{
	int i = 0;
	int iResult = ERR_FAILED;
	IicMsg* pRsp = (IicMsg*)pRspBuff;
	uint8 rspLen  = rspBufLen;
	
	reqlen -= IICMSG_HEAD_SIZE - 1;
	
	for(i = 0; i < count; i++, pTable++)
	{
		if(pReq->cmd == pTable->cmd && pReq->rsNetFn == pTable->netFnLun)
		{
			iResult = pTable->cmdHandler(pReq->smsgBuf, reqlen, pRsp->smsgBuf, &rspLen);
			break;
		}
	}
	
	if(iResult == ERR_FAILED)
	{
		pRsp->smsgBuf[0] = 0xC1;
		rspLen = 1;
	}
	
	rspLen = IicMsg_GetRsp(pReq, pRspBuff, MAX_IPMICMD_LEN, pRsp->smsgBuf, rspLen);
	
	return rspLen;
}

void IpmbTester_Init(IpmbTester* pIpmbTester
	, Queue* pRxQueue
	, Queue* pTxQueue
	, uint8 rA
	, uint8 rLun
	, uint8 lA
	, uint8 lLun
	, IpmbPostMsgFun PostMsg
	, CmdDisptchFun	 CmdDisptch
	)
{
	Trace("%s(), rsSA=0x%x, rsLun=0x%x, rqSA=0x%x, rqLun=0x%x\n", _FUNC_, rA, rLun, lA, lLun);
	//Init Message Queue
	QUEUE_init(&pIpmbTester->m_msgQueue, (uint8*)&pIpmbTester->m_msgQueuePool, sizeof(Message), QUEUE_MAX_ELEMENT);

	TimerManager_Init(&pIpmbTester->m_TimerManager);

	Ipmb_Init(&pIpmbTester->m_Ipmb
		, I2C_CHANNEL_IPMBL
		, PostMsg
		, (IpmiCmdVerifyFun)IicMsg_Verify
		, (IpmiCmdGetHeaderFun)IicMsg_GetHeader
		, CmdDisptch
		);
	IicDriverTester_Init(&pIpmbTester->m_IicDriver, 1, pRxQueue, pTxQueue, (IicDriverCallBackFun)Ipmb_driverCallBack, &pIpmbTester->m_Ipmb);
	Ipmb_AttachTransfer(&pIpmbTester->m_Ipmb, (Transfer*)&pIpmbTester->m_IicDriver);

	QUEUE_init(&pIpmbTester->m_reqDataQueue, pIpmbTester->m_reqDataPool, sizeof(ReqData), IPMB_TEST_MAX_REQDATA_COUNT);
	IicCrb_Init(&pIpmbTester->m_ReqCrb
		, &pIpmbTester->m_TimerManager
		, &pIpmbTester->m_Ipmb
		, True, rA, lA, lLun
		, &pIpmbTester->m_reqDataQueue
		);
	
	IicCrb_Init(&pIpmbTester->m_RspCrb
		, &pIpmbTester->m_TimerManager
		, &pIpmbTester->m_Ipmb
		, False, rA, lA, lLun, Null
		);
	
	pIpmbTester->m_RspCrb.m_Base.m_pRequester = pIpmbTester;
	pIpmbTester->m_RspCrb.m_Base.Notify = (CrbNotifyFun)IpmbTester_CrbTxRspDone;
{
	IicCrb* pIicCrb = &pIpmbTester->m_FroReqCrb;
	memset(pIicCrb, 0, sizeof(IicCrb));
	IicCmd_Init(&pIicCrb->m_ReqIicCmd);
	IicCmd_Init(&pIicCrb->m_RspIicCmd);
	pIicCrb->m_Base.m_pReqIpmiCmd = (IpmiCmd*)&pIicCrb->m_ReqIicCmd;
	pIicCrb->m_Base.m_pRspIpmiCmd = (IpmiCmd*)&pIicCrb->m_RspIicCmd;

	pIicCrb = &pIpmbTester->m_FroRspCrb;
	memset(pIicCrb, 0, sizeof(IicCrb));
	IicCmd_Init(&pIicCrb->m_ReqIicCmd);
	IicCmd_Init(&pIicCrb->m_RspIicCmd);
	pIicCrb->m_Base.m_pReqIpmiCmd = (IpmiCmd*)&pIicCrb->m_ReqIicCmd;
	pIicCrb->m_Base.m_pRspIpmiCmd = (IpmiCmd*)&pIicCrb->m_RspIicCmd;
}
	
	IicCmd_Init(&pIpmbTester->m_receIicCmd);
}

void IpmbTester_CrbDone(IpmbTester* pIpmbTester, Crb* pCrb, uint8 State)
{
	IpmiCmd* pCmd = (IpmiCmd*)&pIpmbTester->m_receIicCmd;
 	uint8* pCmdData = pCrb->m_pRspIpmiCmd->m_pCmdData;
	int nLen = pCrb->m_pRspIpmiCmd->GetDataLen(pCrb->m_pRspIpmiCmd);
	const static char* g_strCrbState[] = 
	{
		  "CRB_INIT"
		, "CRB_READY"
		, "CRB_TX_REQ"
		, "CRB_RETX_REQ"
		, "CRB_TX_RSP"
		, "CRB_RETX_RSP"
		, "CRB_TX_REQ_SUCCESS"
		, "CRB_TX_RSP_SUCCESS"
		, "CRB_RX_REQ_SUCCESS"
		, "CRB_RX_RSP_SUCCESS"
		, "CRB_TX_REQ_FAILED"
		, "CRB_TX_RSP_FAILED"
		, "CRB_RX_RSP_FAILED"
		, "CRB_NO_RSP"
		, "CRB_CANCEL"
		, "CRB_STOP"
	};

	if(CRB_RX_RSP_SUCCESS == pCrb->m_State)
	{
		if(pCmdData[0] == 0/*COMMAND_COMPLETE*/)
		{
		}
		Trace("%s(%s) Cmd[0x%02x],CompleteCode=0x%02x\n"
			, _FUNC_
			, g_strCrbState[State]
			, pCrb->m_pReqIpmiCmd->m_Header.m_Cmd
			, pCmdData[0]
			);
		Trace("\tReceive Rsp Data(%d): ", nLen);
		DUMP_BYTE(pCmdData, nLen);
	}
	else
	{
		Trace("%s(%s) Cmd[0x%02x], rqSeq=0x%02x\n"
			, _FUNC_
			, g_strCrbState[State]
			, pCrb->m_pReqIpmiCmd->m_Header.m_Cmd
			, pCrb->m_pReqIpmiCmd->m_Header.m_NetFn);
	}
	IpmbTester_CrbClone((Crb*)&pIpmbTester->m_FroReqCrb, pCrb);
	memcpy(pCmd->m_pCmd, pCrb->m_pRspIpmiCmd->m_pCmd, pCrb->m_pRspIpmiCmd->m_CmdLen);
	return ;
}

void IpmbTester_SendReq(IpmbTester* pIpmbTester, TestPacket* pReq)
{
	ReqData req;
	Crb * pCrb = (Crb*)&pIpmbTester->m_ReqCrb;

	req.m_Cmd = pReq->m_Cmd;
	req.m_NetFn = pReq->m_NetFn;
	req.m_Lun = 0;
	req.m_reSendCounter = 5;
	req.Notify = (CrbNotifyFun)IpmbTester_CrbDone;
	req.m_len = pReq->m_Len;
	memcpy(req.m_buff, &pReq->m_Cmd, pReq->m_Len);
	req.m_pRequester = pIpmbTester;
	
	Trace("%s() cmd=0x%02x, netFn=0x%x, len=%d\n", _FUNC_, PLATFORM_EVENT_MESSAGE, NETFUN_SSEVENT_REQ, pReq->m_Len);

	((Crb*)&pIpmbTester->m_FroReqCrb)->m_State = CRB_INIT;
	Crb_PostReq(pCrb, &req);	
}

/*
uint8 IpmbTester_GetRsp(IicMsg* pReq, IicMsg* pRsp, uint8* pCmdData, uint8 cmdLen)
{
	int i = 0;
	uint8* pData = (uint8*)pRsp;
	int nLen = IICMSG_HEAD_SIZE + cmdLen + 1;

	memcpy(pRsp, pReq, IICMSG_HEAD_SIZE);
	memcpy(pRsp->smsgBuf, pCmdData, cmdLen);
	
	pRsp->smsgBuf[0] = 0;
	pRsp->rqSA = pReq->rsSA;
	pRsp->rsSA = pReq->rqSA;
	pRsp->rsNetFn = pReq->rsNetFn + 1;
	
	pRsp->checkSum = CheckSum_Get(pData, 2);
	pData[nLen - 1] = CheckSum_Get(&pData[3], nLen - 4);

	Assert(pRsp->rqSeq == pReq->rqSeq);

	return nLen;
}
*/


uint8 IpmbTester_GetCmReq(ReqData * pReq, uint8 rsSA, uint8 rqSA, IicMsg* pCmReq, uint8 cmReqlen)
{
	
	int i = 0;
	uint8* pData = (uint8*)pCmReq;
	int nLen = IICMSG_HEAD_SIZE + pReq->m_len + 1;

	Assert(cmReqlen >= nLen);

	pCmReq->rsSA = rsSA;
	pCmReq->rsLun= pReq->m_Lun;
	pCmReq->rsNetFn = pReq->m_NetFn;
	pCmReq->cmd = pReq->m_Cmd;
	
	pCmReq->rqSA = rqSA;
	pCmReq->rqLun = pReq->m_Lun;
	memcpy(pCmReq->smsgBuf, pReq->m_buff, pReq->m_len);
	
	pCmReq->checkSum = CheckSum_Get(pData, 2);
	pData[nLen - 1] = CheckSum_Get(&pData[3], nLen - 4);
	
	return nLen;	
}

static uint8 IpmbTester_GetCmReqEx(TestPacket * pReq, uint8 rsSA, uint8 rqSA, IicMsg* pCmReq, uint8 cmReqlen)
{
	ReqData reqData = {0};

	reqData.m_Cmd = pReq->m_Cmd;
	reqData.m_NetFn = pReq->m_NetFn;
	reqData.m_reSendCounter = 5;
	reqData.m_len = pReq->m_Len;
	memcpy(reqData.m_buff, pReq->m_CmdData, pReq->m_Len);
	return IpmbTester_GetCmReq(&reqData, rsSA, rqSA, pCmReq, cmReqlen);
}


Bool IpmbTester_TxReqRxRsp(IpmbTester* pIpmbTester, TestPacket* pReq)
{
	int nRet = ERR_FAILED;
	int nCount = 0;
	BusDataPacket rsp;
	IicMsg* pIicMsg = Null;
	Crb* pCrb = ((Crb*)&pIpmbTester->m_FroReqCrb);
	uint8 rspCmdData[10] = {0xA};

	IpmbTester_SendReq(pIpmbTester, pReq);

	while(nCount++ < 500)
	{
		BusDataPacket* pPacket = (BusDataPacket*)QUEUE_popGetHead(pIpmbTester->m_IicDriver.m_pTxQueue);
		if(pPacket)
		{
			sleep(5);

			pIicMsg = (IicMsg*)pPacket->m_Data;
			rsp.m_Len = IicMsg_GetRsp(pIicMsg, rsp.m_Data, BUS_DATAPACKET_SIZE, pReq->m_rspData, pReq->m_rspLen);

			Trace("Tester Send Resp Data(%d): ", pReq->m_Len);
			DUMP_BYTE(pReq->m_rspData, pReq->m_rspLen);
			nRet = Ipmb_driverCallBack(&pIpmbTester->m_Ipmb, EVENT_RX_SUCCESS, rsp.m_Data, rsp.m_Len);
		}

		if(ERR_SUCCESS == nRet && CRB_INIT != pCrb->m_State)
		{
			if(rsp.m_Len <= MAX_IPMICMD_LEN)
			{
				if(pCrb->m_State == CRB_RX_RSP_SUCCESS
					&& memcmp(pReq->m_rspData, pIpmbTester->m_receIicCmd.m_Base.m_pCmdData, pReq->m_rspLen) == 0)
					//&& memcmp(pRspData, pCrb->m_pRspIpmiCmd->m_pCmdData, len) == 0)
				{
					return True;
				}
				else
				{
					return False;
				}
			}
			else
			{
				if(pCrb->m_State == CRB_RX_RSP_FAILED && pCrb->m_ErrorCode == CRB_TIMEOUT)
				{
					return True;
				}
				else
				{
					return False;
				}
			}
		}
		sleep(1);
	}

	return False;
}

Bool IpmbTester_RxReqTxRsp(IpmbTester* pIpmbTester, TestPacket * pReq)
{
	int nRet = 0;
	int nCount = 0;
	BusDataPacket packet;
	Crb* pCrb = (Crb*)&pIpmbTester->m_RspCrb;	

	IpmbTester_Reset(pIpmbTester);
	
	packet.m_Len = IpmbTester_GetCmReqEx(pReq
		, pIpmbTester->m_RspCrb.m_LocalAddr
		, pIpmbTester->m_RspCrb.m_RemoteAddr
		, (IicMsg*)packet.m_Data
		, BUS_DATAPACKET_SIZE);
	nRet = Ipmb_driverCallBack(&pIpmbTester->m_Ipmb, EVENT_RX_SUCCESS, (uint8*)packet.m_Data, packet.m_Len);

	if(packet.m_Len > MAX_IPMICMD_LEN)
	{
		if(nRet == ERR_FAILED)
		{
			goto Ok;
		}
		else
		{
			goto Failed;
		}
	}
	else
	{
		if(nRet != ERR_SUCCESS)
		{
			goto Failed;
		}
	}
	
	pCrb = ((Crb*)&pIpmbTester->m_FroRspCrb);
	while(nCount++ < 500)
	{
		if(CRB_INIT != pCrb->m_State)
		{
			sleep(100);
			if(pCrb->m_State == CRB_TX_RSP_SUCCESS)
			{
				goto Ok;
			}
			else
			{
				goto Failed;
			}
		}
		sleep(1);
	}

Failed:
	IpmbTester_Reset(pIpmbTester);
	return False;
Ok:
	IpmbTester_Reset(pIpmbTester);
	return True;
}

Bool IpmbTester_SendReqFailed(IpmbTester* pIpmbTester, TestPacket * pReq)
{
	int nCount = 0;
	TransferFun temp = pIpmbTester->m_Ipmb.m_pTransfer->TxData;
	Crb* pCrb = ((Crb*)&pIpmbTester->m_FroReqCrb);
	
	pIpmbTester->m_Ipmb.m_pTransfer->TxData = (TransferFun)IicDriverTester_TxDataFailed;

	IpmbTester_SendReq(pIpmbTester, pReq);
	
	while(nCount++ < 500)
	{
		if(CRB_INIT != pCrb->m_State)
		{
			if(pCrb->m_State == CRB_TX_REQ_FAILED)
			{
				goto Ok;
			}
			else
			{
				goto Failed;
			}
		}
		sleep(1);
	}

Failed:
	pIpmbTester->m_Ipmb.m_pTransfer->TxData = temp;
	return False;
Ok:
	pIpmbTester->m_Ipmb.m_pTransfer->TxData = temp;
	return True;
}

Bool IpmbTester_ReqNoRsp(IpmbTester* pIpmbTester, TestPacket * pReq)
{
	int nCount = 0;
	Crb* pCrb = ((Crb*)&pIpmbTester->m_FroReqCrb);

	IpmbTester_SendReq(pIpmbTester, pReq);
	
	while(nCount++ < 1000)
	{
		if(CRB_INIT != pCrb->m_State)
		{
			if(pCrb->m_State == CRB_RX_RSP_FAILED
				&& pCrb->m_ErrorCode == CRB_TIMEOUT)
			{
				goto Ok;
			}
			else
			{
				goto Failed;
			}
		}
		sleep(2);
	}

Failed:
	QUEUE_removeAll(pIpmbTester->m_IicDriver.m_pTxQueue);
	return False;
Ok:
	QUEUE_removeAll(pIpmbTester->m_IicDriver.m_pTxQueue);
	return True;
}

Bool IpmbTester_ReSendReqRsp(IpmbTester* pIpmbTester, TestPacket * pReq, uint8 reSend)
{
	int nCount = 0;
	BusDataPacket rsp;
	IicMsg* pIicMsg = Null;
	Crb* pCrb = ((Crb*)&pIpmbTester->m_FroReqCrb);

	Trace("%s() reSendCount=%d\n", _FUNC_, reSend);

	IpmbTester_SendReq(pIpmbTester, pReq);
	
	while(nCount++ < 1000)
	{
		BusDataPacket* pPacket = (BusDataPacket*)QUEUE_popGetHead(pIpmbTester->m_IicDriver.m_pTxQueue);
		if(pPacket && pIpmbTester->m_ReqCrb.m_Base.m_bTxCount >= reSend)
		{
			sleep(5);

			pIicMsg = (IicMsg*)rsp.m_Data;
			rsp.m_Len = IicMsg_GetRsp((IicMsg*)pPacket->m_Data, rsp.m_Data, BUS_DATAPACKET_SIZE, pReq->m_rspData, pReq->m_rspLen);
			//rsp.m_Len = IpmbTester_GetRsp((IicMsg*)pPacket->m_Data,  pIicMsg, pReq->m_rspData, pReq->m_rspLen);

			Trace("Response cmd=0x%02x, netFn=0x%x, len=%d\n", pIicMsg->cmd, pIicMsg->rsNetFn, pReq->m_rspLen);
			Ipmb_driverCallBack(&pIpmbTester->m_Ipmb, EVENT_RX_SUCCESS, rsp.m_Data, rsp.m_Len);

		}
		
		if(CRB_INIT != pCrb->m_State)
		{
			if(pCrb->m_State == CRB_RX_RSP_SUCCESS
				&& memcmp(pReq->m_rspData, pIpmbTester->m_receIicCmd.m_Base.m_pCmdData, pReq->m_rspLen) == 0)
			{
				goto Ok;
			}
			else
			{
				goto Failed;
			}
		}
		sleep(2);
	}

Failed:
	QUEUE_removeAll(pIpmbTester->m_IicDriver.m_pTxQueue);
	return False;
Ok:
	QUEUE_removeAll(pIpmbTester->m_IicDriver.m_pTxQueue);
	return True;
}


Bool IpmbTester_RecInvalidPacket(IpmbTester* pIpmbTester, TestPacket * pReq, uint8 invalidByte)
{
	int nCount = 0;
	BusDataPacket rsp;
	IicMsg* pIicMsg = Null;
	Crb* pCrb = ((Crb*)&pIpmbTester->m_FroReqCrb);

	IpmbTester_SendReq(pIpmbTester, pReq);

	while(nCount++ < 1000)
	{
		BusDataPacket* pPacket = (BusDataPacket*)QUEUE_popGetHead(pIpmbTester->m_IicDriver.m_pTxQueue);
		if(pPacket)
		{
			sleep(1);

			pIicMsg = (IicMsg*)rsp.m_Data;
			rsp.m_Len = IicMsg_GetRsp((IicMsg*)pPacket->m_Data, rsp.m_Data, BUS_DATAPACKET_SIZE, pReq->m_rspData, pReq->m_rspLen);
			//rsp.m_Len = IpmbTester_GetRsp((IicMsg*)pPacket->m_Data,  pIicMsg, pReq->m_rspData, pReq->m_rspLen);
			
			rsp.m_Data[invalidByte%MAX_IPMICMD_LEN]++;

			Trace("Response cmd=0x%02x, netFn=0x%x, len=%d\n", pIicMsg->cmd, pIicMsg->rsNetFn, pReq->m_rspLen);
			Ipmb_driverCallBack(&pIpmbTester->m_Ipmb, EVENT_RX_SUCCESS, rsp.m_Data, rsp.m_Len);

		}

		if(CRB_INIT != pCrb->m_State)
		{
			if(pCrb->m_State == CRB_RX_RSP_FAILED)
			{
				return True;
			}
			else
			{
				return False;
			}
		}
		sleep(2);
	}

	return False;
}

Bool IpmbTester_RxMoreThenOneReq(IpmbTester* pIpmbTester, TestPacket * pReq, int nSendCount)
{
	int i = 0;
	int nIndex = 0;
	int nRet = 0;
	int nCount = 0;
	BusDataPacket packet;
	Crb* pCrb = ((Crb*)&pIpmbTester->m_FroRspCrb);

	IpmbTester_Reset(pIpmbTester);

	packet.m_Len = IpmbTester_GetCmReqEx(pReq
		, pIpmbTester->m_RspCrb.m_LocalAddr
		, pIpmbTester->m_RspCrb.m_RemoteAddr
		, (IicMsg*)packet.m_Data
		, BUS_DATAPACKET_SIZE);

	for(i = 0; i < nSendCount; i++)
	{
		nRet = Ipmb_driverCallBack(&pIpmbTester->m_Ipmb, EVENT_RX_SUCCESS, (uint8*)packet.m_Data, packet.m_Len);
		
		if(nRet == ERR_SUCCESS)
		{
			nIndex++;
		}
	}
	
	while(nCount++ < 1000)
	{
		if(CRB_INIT != pCrb->m_State)
		{
			if(CRB_TX_RSP_SUCCESS == pCrb->m_State )
			{
				goto Ok;
			}
			else
			{
				goto Failed;
			}
		}
		sleep(2);
	}

Failed:
	IpmbTester_Reset(pIpmbTester);
	return False;
Ok:
	IpmbTester_Reset(pIpmbTester);
	return True;
}

Bool IpmbTester_TxReqRxRspAndReq(IpmbTester* pIpmbTester, TestPacket * pTxReq, TestPacket * pRxReq)
{
	int nCount = 0;
	BusDataPacket rsp;
	BusDataPacket packet;
	IicMsg* pIicMsg = Null;
	Crb* pCrb = ((Crb*)&pIpmbTester->m_FroReqCrb);
	Crb* pForRspCrb = ((Crb*)&pIpmbTester->m_FroRspCrb);

	IpmbTester_Reset(pIpmbTester);
	
	IpmbTester_SendReq(pIpmbTester, pTxReq);

	while(nCount++ < 500)
	{
		BusDataPacket* pPacket = (BusDataPacket*)QUEUE_popGetHead(pIpmbTester->m_IicDriver.m_pTxQueue);
		if(pPacket)
		{
			sleep(5);

			pIicMsg = (IicMsg*)rsp.m_Data;
			rsp.m_Len = IicMsg_GetRsp((IicMsg*)pPacket->m_Data, rsp.m_Data, BUS_DATAPACKET_SIZE, pTxReq->m_rspData, pTxReq->m_rspLen);
			//rsp.m_Len = IpmbTester_GetRsp((IicMsg*)pPacket->m_Data,  pIicMsg, pTxReq->m_rspData, pTxReq->m_rspLen);

			Trace("Response cmd=0x%02x, netFn=0x%x, len=%d\n", pIicMsg->cmd, pIicMsg->rsNetFn, pTxReq->m_rspLen);
			Ipmb_driverCallBack(&pIpmbTester->m_Ipmb, EVENT_RX_SUCCESS, rsp.m_Data, rsp.m_Len);

			packet.m_Len = IpmbTester_GetCmReqEx(pRxReq
				, pIpmbTester->m_RspCrb.m_LocalAddr
				, pIpmbTester->m_RspCrb.m_RemoteAddr
				, (IicMsg*)packet.m_Data
				, BUS_DATAPACKET_SIZE);
			Ipmb_driverCallBack(&pIpmbTester->m_Ipmb, EVENT_RX_SUCCESS, packet.m_Data, packet.m_Len);
		}

		if(CRB_INIT != pCrb->m_State && pForRspCrb->m_State != CRB_INIT)
		{
			if(CRB_RX_RSP_SUCCESS == pCrb->m_State && pForRspCrb->m_State == CRB_TX_RSP_SUCCESS)
			{
				return True;
			}
		}

		sleep(1);
	}

	return False;
}

#endif

